﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.Collections.Generic;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using Xceed.Silverlight.Data;

namespace Xceed.Silverlight.DataGrid
{
  internal static class MiscellaneousExtensions
  {

    public static bool IsIncrement( this Key key )
    {
      if( ( key == Key.Left )
        || ( key == Key.Up )
        || ( key == Key.PageUp )
        || ( key == Key.Home ) )
      {
        return false;
      }
      else if( ( key == Key.Right )
        || ( key == Key.Down )
        || ( key == Key.PageDown )
        || ( key == Key.End ) )
      {
        return true;
      }

      throw new ArgumentException( "The specified key does not represent a scroll displacement.", "key" );
    }

    public static bool IsPage( this Key key )
    {
      return ( key == Key.PageDown )
        || ( key == Key.PageUp );
    }

    public static bool IsLine( this Key key )
    {
      return ( key == Key.Down )
        || ( key == Key.Up );
    }

    public static bool IsHomeEnd( this Key key )
    {
      return ( key == Key.Home )
        || ( key == Key.End );
    }

    public static bool IsForward( this FetchDirection layoutDirection )
    {
      return ( layoutDirection == FetchDirection.Forward );
    }

    public static FetchDirection Reverse( this FetchDirection layoutDirection )
    {
      return ( layoutDirection == FetchDirection.Forward )
        ? FetchDirection.Backward
        : FetchDirection.Forward;
    }

    public static bool IsPage( this DataGridControl.NavigationOperation navigationOperation )
    {
      return ( navigationOperation == DataGridControl.NavigationOperation.NextPage )
        || ( navigationOperation == DataGridControl.NavigationOperation.PreviousPage );
    }

    public static bool IsIncrement( this DataGridControl.NavigationOperation navigationOperation )
    {
      return ( navigationOperation == DataGridControl.NavigationOperation.NextPage )
        || ( navigationOperation == DataGridControl.NavigationOperation.NextItem );
    }

    public static bool IsLast( this ScrollEventType scrollEventType )
    {
      return ( scrollEventType == ScrollEventType.Last );
    }

    public static bool IsFirst( this ScrollEventType scrollEventType )
    {
      return ( scrollEventType == ScrollEventType.First );
    }

    public static bool IsThumbTrack( this ScrollEventType scrollEventType )
    {
      return ( scrollEventType == ScrollEventType.ThumbTrack );
    }

    public static bool IsIncrement( this ScrollEventType scrollEventType )
    {
      return ( scrollEventType == ScrollEventType.SmallIncrement )
        || ( scrollEventType == ScrollEventType.LargeIncrement );
    }

    public static bool IsDecrement( this ScrollEventType scrollEventType )
    {
      return ( scrollEventType == ScrollEventType.SmallDecrement )
        || ( scrollEventType == ScrollEventType.LargeDecrement );
    }

    public static bool IsSmallChange( this ScrollEventType scrollEventType )
    {
      return ( scrollEventType == ScrollEventType.SmallIncrement )
        || ( scrollEventType == ScrollEventType.SmallDecrement );
    }

    public static bool IsLargeChange( this ScrollEventType scrollEventType )
    {
      return ( scrollEventType == ScrollEventType.LargeIncrement )
        || ( scrollEventType == ScrollEventType.LargeDecrement );
    }

    public static RelativeOffset GetFirstItemOffset( this JumpMoveAndFetchResult<DataPath> result )
    {
      return MiscellaneousExtensions.GetFirstItemOffset( 
        result.ExpectedFetchCount, 
        result.FetchedItems, 
        result.EndPositionObject,
        result.EndPositionOffset );
    }

    public static RelativeOffset GetFirstItemOffset( this PeekResult<DataPath> result )
    {
      return MiscellaneousExtensions.GetFirstItemOffset(
        result.ExpectedPeekCount,
        result.PeekedItems,
        result.EndPositionObject,
        result.EndPositionOffset );
    }

    private static RelativeOffset GetFirstItemOffset(
      int expectedFetchCount, 
      ICollection<DataPath> fetchedItems,
      SourcePosition endPositionObject,
      RelativeOffset lastItemOffset )
    {
      if( lastItemOffset != null )
      {
        if( fetchedItems != null )
        {
          int directionFactor = ( DataUtils.GetUnit(expectedFetchCount) == 1 ) == ( lastItemOffset.ReferencePosition == ReferencePoint.AfterLast )
            ? -1
            : 1;

          //If the fetch is incomplete because it tried to fetch
          //after the last (or before the first), the endPosition offset will 
          //represent the offset "before first" or "after last" at 0;
          int adjustmentFactor = ( endPositionObject.IsOutOfBound ) 
            ? fetchedItems.Count
            : fetchedItems.Count - 1;

          lastItemOffset -= ( adjustmentFactor * directionFactor );

          return lastItemOffset;
        }
      }

      return null;
    }
  }
}
